package org.libermundi.theorcs.core.services;

import java.io.Serializable;
import java.util.List;

import javax.persistence.EntityManager;

import org.libermundi.theorcs.core.dao.GenericDao;
import org.libermundi.theorcs.core.model.base.Identifiable;


/**
 * Interface of any Manager Service
 *
 */
public interface Manager<T extends Identifiable<I>,I extends Serializable> {
	/**
	 * Used to re-attach the Object to the Session (Hibernate for example).
	 * Merge the state of the given entity into the current persistence context.
	 * @see EntityManager#merge(Object)
	 * @param obj Object to re-attach
	 */
	void refresh(T obj);
	
	/**
	 * Get Object by Id
	 * @param id
	 * @return Object
	 */
	T load(I id);
	
	/**
	 * Get the Object with the Highest Id
	 * 
	 * @return Object
	 */
	T loadLast();
	
	/**
	 * Persist (if id is null) or Merge one entity.
	 * @param entity
	 */
	public void save(T entity);

	/**
	 * Persist (if id is null) or Merge array of entities.
	 * @param entities
	 */
	@SuppressWarnings("unchecked")
	public void save(T... entities);
	
	/**
	 * Duplicate the Object
	 * @param original Object to duplicate
	 * @return duplicated Object
	 */
	T duplicate(T original);

	/**
	 * Duplicate the Object with the ability to reset the Primary Key
	 * @param original Object to duplicate
	 * @param resetPrimaryKey boolean to reset or not the Primary  Key in duplicating the object
	 * @return duplicated Object
	 */
	T duplicate(T original, boolean resetPrimaryKey);
	
	/**
	 * Delete the object defined by id
	 * @param id int
	 */
	void delete(I id);
	
	/**
	 * Delete the object defined by id
	 * @param object object
	 */
	void delete(T object);
	
	/**
	 * Get all Object and return them into a List
	 * @return List of Object 
	 */
	List<T> getAll();
	
	/**
	 * Make a simple "select count(*)"
	 * @return the total numbers of managed items in the database
	 */
	
	Long getAllCount();
	
	/**
	 * Flush the transaction
	 */
	void flush();
	
	/**
	 * Getter of the DAO of the Service Manager
	 * @return the instance of the Dao used by the Manager
	 */
	GenericDao<T,I> getDao();

	/**
	 * Setter of the DAO of the Service Manager
	 * @param dao
	 */
	void setDao(GenericDao<T,I> dao);
	
	/**
	 * To be used at Application start. Check if the default datas are in the DB, if not, creates them.
	 * 
	 */
	void initialize();

}
